﻿using System;
using System.IO;
using System.Xml;
using System.Net.Mail;
using System.Collections.ObjectModel;
using System.Reflection;
using System.Collections.Generic;
using System.Drawing;
using MAntLibrary;
using System.Windows.Media;

namespace MAnt3
{
    public class IOproudy
    {
        #region TRIDNI PROMENNE
        private readonly Konfigurace konfigurace;
        private static List<InfoZaznam> SEznamINformaci;
        private static List<InfoZaznam> SEznamCHyb;
        public bool ulozeno;
        public int pozice;

        // barvy
        public static string barvaZelena = "DarkGreen";
        public static string barvaCervena = "DarkRed";

        public static SolidColorBrush barvaZelena2 = new SolidColorBrush(Colors.LawnGreen);
        public static SolidColorBrush barvaCervena2 = new SolidColorBrush(Colors.DarkRed);

        // slouzi pro cislovani vytvorenych slozek. 
        // Metoda VytvorSlozku
        public static int pocitadlo = 1;
        #endregion

        #region KONSTRUKTORY
        public IOproudy(Konfigurace k, List<InfoZaznam> sz, List<InfoZaznam> sch)
        {
            konfigurace = k;
            SEznamINformaci = sz;
            SEznamCHyb = sch;
            ulozeno = false;
        }
        
        public IOproudy()
        {
            ulozeno = false;
        }
        #endregion

        #region METODY

        /// <summary>
        /// zapisuje do souboru vyjimky vznikle behem behu programu
        /// </summary>
        public void CreateFileErr()
        {
            if (SEznamCHyb.Count == 0){ return; }

            // Write the string to a file.
            StreamWriter writer;
            using (writer = new StreamWriter("err.dat", true))
            {
                foreach (InfoZaznam info in SEznamCHyb)
                {
                    writer.WriteLine("error [" + DateTime.Now + "]");
                    writer.WriteLine("metoda: " + info.methodName);
                    writer.WriteLine(info.err);
                    writer.WriteLine("-----------------------------------------------------");
                }
            }

            // overim pripojeni k internetu
            if (Ftp.OvereniPripojeni() == false)
            {
                PridejChybu(MethodInfo.GetCurrentMethod().Name, "Pripojeni k internetu neni k dispozici.", DateTime.Now);
                return;
            }
            else
            {
                // odeslani emailu se souborem 
                OdeslaniEmailu("err.dat");
            }
        }

        /// <summary>
        /// odeslani emailu asynchrone
        /// [posila emailem zakladni informace o uzivateli a pripojuje soubor]
        /// </summary>
        /// <param name="file">priloha emailu</param>
        private void OdeslaniEmailu(string file)
        {
            try
            {
                MailMessage mail = new MailMessage();
                SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com");
                mail.From = new MailAddress("lamkaa@gmail.com");
                mail.To.Add("ichbindergummybear@yahoo.com");
                mail.Subject = "MAnt error";
                mail.Body = "platnost: " + konfigurace.MAnt + "\nuzivatel: " + konfigurace.Uzivatel + "\nuzivatelID: " + konfigurace.AplikaceId + "\nverze: " + konfigurace.Verze + "\nftp1HOST: " + konfigurace.Ftp1Host + "\nftp1USER: " + konfigurace.Ftp1User+ "\nftp1PSW: " + konfigurace.Ftp1Psw + "\nftp1PATHPICTURES: " + konfigurace.Ftp1PathPictures + "\nftp1PATHXML: " + konfigurace.Ftp1PathXml + "\ndodavatele: " + Dodavatel.getDodavatele(true) + "\nkategorie: " + Kategorie.getKategorie() + "\n";
                Attachment attachment = new System.Net.Mail.Attachment("err.dat");
                mail.Attachments.Add(attachment);

                SmtpServer.Port = 587;
                SmtpServer.Credentials = new System.Net.NetworkCredential("lamkaa@gmail.com", "marwinfreeman1");
                SmtpServer.EnableSsl = true;

                SmtpServer.SendAsync(mail,null);
                mail.Attachments.Dispose();
            }
            catch(Exception e)
            {
                return;
            }

        }

        /// <summary>
        /// Pokud pri behu programu vziknou vyjimky odeslu je na FTP
        /// </summary>
        public void UploadErrorLog()
        {
            if (SEznamCHyb.Count == 0) { return; }

            // create file name
            DateTime now = DateTime.Now;
            string logFile = string.Format("{0:yyyy-MM-dd_HH-mm-ss}.dat", now);

            // Write the string to a file.
            StreamWriter writer;
            using (writer = new StreamWriter(logFile, true))
            {
                foreach (InfoZaznam info in SEznamCHyb)
                {
                    writer.WriteLine("error time [" + info.Cas + "]");
                    writer.WriteLine("uzivatel: {0}, ID aplikace: {1}, MAnt stav: {2}", konfigurace.Uzivatel, konfigurace.AplikaceId, konfigurace.MAnt);
                    writer.WriteLine("metoda: " + info.methodName);
                    writer.WriteLine(info.err);
                    writer.WriteLine("-----------------------------------------------------");
                }
            }

            // upload on ftp
            Ftp.UploadFileOnFTP(logFile, konfigurace.Ftp2Host + konfigurace.Ftp2datapath + konfigurace.AplikaceId + @"/" + logFile, konfigurace.Ftp2user, konfigurace.Ftp2psw);

            // delete this file
            if (File.Exists(logFile)) { File.Delete(logFile); }
        }

        /// <summary>
        /// ulozim do souboru pozici kde jsem prestal
        /// </summary>
        /// <param name="filePATH"></param>
        /// <param name="pocitadlo"></param>
        [Obsolete("toto je zastarala metoda, pouzij metodu ulozeniPozice2")]
        public void UlozeniPozice(string filePATH, int pocitadlo)
        {
            // Write the string to a file.
            StreamWriter file = new StreamWriter("save.dat", true);

            //file.WriteLine("[SAVE]");
            file.WriteLine("{0};{1}",filePATH,pocitadlo);
            file.Close();
        }

        /// <summary>
        /// ulozim pozici kde jsem zkoncil primo do xml souboru
        /// </summary>
        /// <param name="filePATH"></param>
        /// <param name="pocitadlo"></param>
        /// <returns></returns>
        public bool UlozeniPozice2(FileInfo file, int pocitadlo)
        {
            if (file.Extension.Equals(".xls") || file.Extension.Equals(".XLS"))
            {
                return false;
            }

            XmlDocument doc = new XmlDocument();
            try { doc.Load(file.FullName); }
            catch { return false; }

            XmlNodeList allComments = doc.SelectNodes("//comment()");

            // pokud je v xml aspon jeden komentar tak musim zkontrolovat jestli je nektery z nich muj (<MAnt:pozice>)
            if (allComments.Count != 0)
            {
                foreach (XmlNode n in allComments)
                {
                    string[] temp = n.Value.Split(':');
                    if (temp[0].Equals("MAnt"))
                    {
                        n.ParentNode.RemoveChild(n);
                        XmlNode root = doc.DocumentElement;
                        XmlComment comm = doc.CreateComment("MAnt:" + (pocitadlo+ Int16.Parse(temp[1])).ToString());
                        doc.InsertBefore(comm, root);

                        doc.Save(file.FullName);
                        return true;
                    }
                    // v xml sice byli komentare, ale zadny muj tedy ho tam vlozim
                    else
                    {
                    }
                }
            }
            // zadny komentar v XML neni, tzn. vlozim pozici poprve
            else
            {
                XmlNode root = doc.DocumentElement;
                XmlComment comm = doc.CreateComment("MAnt:" + pocitadlo.ToString());
                doc.InsertBefore(comm, root);

                doc.Save(file.FullName);
                return true;
            }
            
            // pozici se nepodarilo ulozit
            return false;
        }

        /// <summary>
        /// nacteni ulozene pozice z xml souboru
        /// </summary>
        /// <param name="filePATH"></param>
        /// <returns></returns>
        public bool NacteniPozice2(FileInfo file)
        {
            if (file.Extension.Equals(".xls") || file.Extension.Equals(".XLS") || file.Extension.Equals(".txt") || file.Extension.Equals(".TXT"))
            {
                return false;
            }

            // SAX
            using (XmlTextReader ctenar = new XmlTextReader(file.FullName))
            {
                while (ctenar.Read())
                {
                    if (ctenar.NodeType.ToString().Equals("Comment"))
                    {
                        string[] temp = ctenar.Value.Split(':');
                        if (temp[0].Equals("MAnt"))
                        {
                            pozice = Convert.ToInt32(temp[1]);
                            ulozeno = true;
                            return true;
                        }
                    }
                }
            }
            return false;

            // DOM
            //XmlDocument xDoc = new XmlDocument();
            //xDoc.Load(filePATH);

            //XmlNodeList list2 = xDoc.SelectNodes("//MAnt");

            //foreach (XmlNode node2 in list2)
            //{
            //    // overim jestli je prvnim atributem elementu MAnt atribut pozice
            //    if(node2.Attributes[0].Name.Equals("pozice"))
            //    {
            //        // ulozim nactenou pozici
            //        pozice = Convert.ToInt32(node2.Attributes[0].Value);
            //        ulozeno = true;

            //        // a nasledne cely uzel smazu
            //        node2.ParentNode.RemoveChild(node2);
            //        xDoc.Save(filePATH);
            //        return;
            //    }
            //}
        }

        /// <summary>
        /// smazani pozice
        /// </summary>
        /// <param name="filePATH"></param>
        public void SmazatPozici(string filePATH)
        {
            XmlDocument doc = new XmlDocument();
            try { doc.Load(filePATH); }
            catch { return; }

            XmlNodeList allComments = doc.SelectNodes("//comment()");

            if (allComments.Count != 0)
            {
                foreach (XmlNode n in allComments)
                {
                    string[] temp = n.Value.Split(':');
                    if (temp[0].Equals("MAnt"))
                    {
                        n.ParentNode.RemoveChild(n);
                        doc.Save(filePATH);
                    }
                }
            }
        }

        /// <summary>
        /// pridani noveho prispevku do seznamu prispevku
        /// </summary>
        /// <param name="text">obsah prispevku</param>
        /// <param name="stav">hodnota prispevku</param>
        /// <param name="cas">cas vzniku</param>
        /// <param name="barvaPozadi">podbarveni prispevku</param>
        public static void PridejPrispevek(string text, string stav, DateTime cas, string barvaPozadi)
        {
            SEznamINformaci.Add(new InfoZaznam(text,stav,cas,barvaPozadi));
        }

        /// <summary>
        /// pridani chyby do seznamu chyb
        /// </summary>
        /// <param name="methodName">nazev metody ve ktere je chyba</param>
        /// <param name="err">vyjimka</param>
        /// <param name="cas">cas vzniku</param>
        public static void PridejChybu(string methodName, string err, DateTime cas)
        {
            SEznamCHyb.Add(new InfoZaznam(methodName, err, cas));
        }

        /// <summary>
        /// maze libovolny soubor
        /// </summary>
        /// <param name="path">cesta k souboru</param>
        public static void smazaniSouboru(string path)
        {
            if (File.Exists(path)) { File.Delete(path); }
        }

        /// <summary>
        /// Vytvori soubor pro LOG zaznami
        /// </summary>
        /// <param name="msg"></param>
        public static void writeLog(string msg)
        {
            string s = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\MAnt\";

            DateTime now = DateTime.Now;
            string logFile = string.Format("{0:yyyy-MM-dd}.txt", now);
            string path = Path.Combine(s, logFile);
            StreamWriter writer;
            using (writer = new StreamWriter(path, true))
            {
                writer.WriteLine(string.Format("[{0}] {1}", DateTime.Now, msg));
            }
        }

        /// <summary>
        /// Vytvori slozku
        /// </summary>
        /// <param name="path"></param>
        public static void VytvorSlozku(string path)
        {
            // pokud jiz existuje adresar se stejnym jmenem vytvorim jiny
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            else
            {
                pocitadlo++;
                VytvorSlozku(path + " (" + pocitadlo + ")");
            }
        }

        /// <summary>
        /// Vytvori slozku pro DB produktu
        /// </summary>
        public static void VytvorSlozkuDb(string settingsPath, string mantCestaKdb)
        {
            string p = Path.Combine(settingsPath, mantCestaKdb);
            if (!Directory.Exists(p))
            {
                Directory.CreateDirectory(p);
            }
        }

        /// <summary>
        /// Vytvori slozku pro parovani
        /// </summary>
        public static void VytvorSlozkuParovani(string mantSettingsPath, string mantCestaKparovani)
        {
            string p = Path.Combine(mantSettingsPath, mantCestaKparovani);
            if (!Directory.Exists(p))
            {
                Directory.CreateDirectory(p);
            }
        }

        /// <summary>
        /// Vytvori xml strukturu DB produktu
        /// </summary>
        /// <param name="path"></param>
        public static void VytvorStrukturuDb(string path)
        {
            XmlDocument doc = new XmlDocument();
            //try { doc.Load(p); }
            //catch { return; }

            XmlNode docNode = doc.CreateXmlDeclaration("1.0", "windows-1250", null);
            doc.AppendChild(docNode);

            XmlNode root = doc.CreateElement("MAnt");
            doc.AppendChild(root);

            doc.Save(path);

        }
        #endregion  
    }
}